package org.xiaov.framework.core;

import cn.hutool.core.util.StrUtil;
import org.xiaov.framework.exception.BizException;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Thread本地上下文
 *
 * @author xiaovcloud
 * @since 2021/11/27 14:58
 */
public final class ThreadContext {
	private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL = new ThreadLocal<>();

	/**
	 * 无参构造
	 */
	private ThreadContext() {
	}

	/**
	 * 保存数据
	 *
	 * @param key   key
	 * @param value value
	 */
	public static void setAttribute(String key, Object value) {
		getAttributes().put(key, value);
	}

	/**
	 * 获取所有本地线程值
	 *
	 * @return Map
	 */
	public static Map<String, Object> getAttributes() {
		Map<String, Object> attributes = THREAD_LOCAL.get();
		if (attributes == null) {
			attributes = new ConcurrentHashMap<>(32);
			THREAD_LOCAL.set(attributes);
		}
		return attributes;
	}

	/**
	 * 根据key获取本地变量
	 *
	 * @param key   key
	 * @param clazz 类型
	 * @param <T>   泛型
	 * @return T
	 */
	public static <T> T getAttribute(String key, Class<T> clazz) {
		if (StrUtil.isEmpty(key)) {
			throw new BizException("key不能为空");
		}
		Object result = getAttributes().get(key);
		return (T) result;
	}

	/**
	 * 本地变量是否包含key
	 *
	 * @param key key
	 * @return 是否存在
	 */
	public static boolean containsAttribute(String key) {
		if (StrUtil.isEmpty(key)) {
			throw new BizException("key不能为空");
		}
		return getAttributes().containsKey(key);
	}

	/**
	 * 根据key移除本地变量
	 *
	 * @param key key
	 */
	public static void removeAttribute(String key) {
		getAttributes().remove(key);
	}

	/**
	 * 清楚所有的本地变量
	 */
	public static void clearAttributes() {
		THREAD_LOCAL.remove();
	}

}
